package com.hup.sidebar.view;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.alibaba.fastjson.JSON;
import com.hup.sidebar.R;
import com.hup.sidebar.SideBarApplication;
import com.hup.sidebar.framework.SubThreadHandler;
import com.hup.sidebar.framework.util.AsyncDrawableTask;
import com.hup.sidebar.framework.util.SpUtil;
import com.hup.sidebar.framework.view.BaseAdapter;
import com.hup.sidebar.framework.view.BaseViewHolder;
import com.hup.sidebar.model.AppConfig;
import com.hup.sidebar.model.AppInfoItem;

import java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * @author hugan
 * @date 2022/6/18
 */
@SuppressLint("NonConstantResourceId")
public class WhiteListActivity extends AppCompatActivity implements OnClickListener {
    private static final String TAG = WhiteListActivity.class.getSimpleName();

    @BindView(R.id.txtTips)
    TextView txtTips;
    @BindView(R.id.lvApp)
    ListView lvApp;

    private AppItemAdapter appAdapter;

    private AppConfig appConfig;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate: ");
        appConfig = SideBarApplication.getBean(AppConfig.class);

        setContentView(R.layout.white_list_activity);
        ButterKnife.bind(this);

        txtTips.setVisibility(appConfig.accessibilityStarted ? View.GONE : View.VISIBLE);
        appAdapter = new AppItemAdapter(this);
        lvApp.setAdapter(appAdapter);

        SideBarApplication.getBean(SubThreadHandler.class).post(() -> {
            PackageManager packageManager = getPackageManager();
            ArrayList<AppInfoItem> items = new ArrayList<>();
            for (String packageName : appConfig.whiteList) {
                try {
                    ApplicationInfo info = packageManager.getApplicationInfo(packageName, 0);
                    items.add(new AppInfoItem(info, packageManager));
                } catch (NameNotFoundException e) {
                    Log.e(TAG, "找不到app: " + packageName);
                }
            }
            this.runOnUiThread(() -> appAdapter.setData(items));
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.white_list_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if (item.getItemId() == R.id.menu_add) {
            Log.d(TAG, "onOptionsItemSelected: menu_add");
            SelectAppActivity.startActivityForResult(this, null);
        }
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.i(TAG, "onActivityResult: " + requestCode + ", " + resultCode);
        if (requestCode == SelectAppActivity.REQUEST_CODE) {
            if (resultCode != RESULT_OK) {
                Log.i(TAG, "onActivityResult: 取消选择");
                return;
            }
            String packageName = SelectAppActivity.getResultPackage();
            SelectAppActivity.afterHandleActivityResult();
            try {
                PackageManager packageManager = getPackageManager();
                ApplicationInfo info = packageManager.getApplicationInfo(packageName, 0);
                appAdapter.addLastItem(new AppInfoItem(info, packageManager));
                appConfig.whiteList.add(packageName);
                saveAppConfig();
            } catch (NameNotFoundException e) {
                Log.e(TAG, "找不到app: " + packageName);
            }
        }
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.btnDelete) {
            int position = (int) v.getTag();
            Log.i(TAG, "onClick: delete=" + position);
            appAdapter.removeItem(position);
            appConfig.whiteList.remove(position);
            saveAppConfig();
        }
    }

    /**
     * 保存配置
     */
    private void saveAppConfig() {
        String str = JSON.toJSONString(appConfig.whiteList);
        Log.i(TAG, "saveAppConfig: " + str);
        SpUtil.apply(appConfig.getSp(this), "whiteList", str);
    }

    private static class AppItemAdapter extends BaseAdapter<AppInfoItem, WhiteAppViewHolder> {
        private final WhiteListActivity activity;

        public AppItemAdapter(WhiteListActivity activity) {
            this.activity = activity;
        }

        @Override
        public int getLayoutResId() {
            return R.layout.white_list_app_item;
        }

        @Override
        public WhiteAppViewHolder createHolder() {
            return new WhiteAppViewHolder(activity);
        }
    }

    public static class WhiteAppViewHolder implements BaseViewHolder<AppInfoItem> {
        @BindView(R.id.imgIcon)
        ImageView imgIcon;
        @BindView(R.id.txtAppName)
        TextView txtAppName;
        @BindView(R.id.txtAppPackage)
        TextView txtAppPackage;
        @BindView(R.id.btnDelete)
        ImageView btnDelete;

        private final PackageManager packageManager;
        private final WhiteListActivity activity;

        public WhiteAppViewHolder(WhiteListActivity activity) {
            this.packageManager = activity.getPackageManager();
            this.activity = activity;
        }

        @Override
        public void onBindView(View view) {
            btnDelete.setOnClickListener(activity);
        }

        @SuppressLint({"StaticFieldLeak"})
        @Override
        public void bindData(int position, AppInfoItem item) {
            txtAppName.setText(item.name);
            txtAppPackage.setText(item.packageName);
            btnDelete.setTag(position);

            /*
            这里的AsyncTask不会导致内存泄露!
            说明详见 AsyncDrawableTask.onPostExecute
             */
            new AsyncDrawableTask(imgIcon) {
                @Override
                protected Drawable doInBackground(Void... voids) {
                    return item.applicationInfo.loadIcon(packageManager);
                }
            }.execute();
        }
    }

}
